Skip to content

feat!: enable remote customer-cloud storage bindings (ALIEN-291)#156

Open
lilienblum wants to merge 76 commits into
mainfrom
lilienblum/alien-291-remote-bindings
Open

feat!: enable remote customer-cloud storage bindings (ALIEN-291)#156
lilienblum wants to merge 76 commits into
mainfrom
lilienblum/alien-291-remote-bindings

Conversation

@lilienblum

@lilienblum lilienblum commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Tracks ALIEN-291.

Summary

  • Add an authoritative manager binding-resolution endpoint for remote, customer-cloud Storage resources.
  • Expose Rust, N-API, and TypeScript remote-storage bindings with bounded credential refresh, manager rediscovery, and one retry after reassignment or stale authorization.
  • Provision exact AWS S3, GCP Cloud Storage, and Azure Blob grants while preserving provider-appropriate ownership across setup, import, update, and teardown.
  • Reconcile durable Azure worker dependencies, exact-scope role assignments, and Event Grid delivery across restart, import, and legacy checkpoints.
  • Add a public BYOB Storage example and hosted smoke coverage for put, get, head, list, and delete.
  • Regenerate the public OpenAPI and client artifacts from their source schemas.
  • Add a packages/commands/README.md so the published @alienplatform/commands package has a landing page. It documents the standalone sender and the pull receiver, the ALIEN_COMMANDS_* environment, and the { managerUrl, deploymentId, token } client contract that ships today.

Security and ownership

  • Resolution requires the exact deployment/resource, current release, assigned manager, operational deployment state, remote-enabled managed Storage, and the dedicated remote-binding capability.
  • Bearer tokens are not forwarded across service boundaries. Manager discovery and short-lived binding tokens are cached separately and refreshed independently.
  • AWS credentials carry an exact bucket session policy; Azure returns one-container user-delegation SAS; GCP uses a Credential Access Boundary backed by the generated exact custom role for storage/remote-data-write.
  • The customer-cloud management role's storage grants are emitted and owned by setup (CloudFormation and Terraform). The runtime observes the imported management identity and never creates or attaches IAM policies, roles, or role assignments at runtime, so the management identity stays inside the least-privilege boundary setup defined. When the imported management resource is setup-owned, the runtime controller skips grant creation on create, update, and delete for all of AWS, GCP, and Azure.
  • Azure role-assignment cleanup requires a deterministic assignment identity plus provider-returned principal proof at the exact resource scope; opaque persisted IDs never authorize deletion.
  • Direct or unproven GCP credentials fail closed. Credential exchange response bodies and submitted credentials are never serialized into errors.

Breaking changes

  • Remove the unscoped /v1/resolve-credentials route.
  • Replace BindingsProvider::for_remote_deployment with Bindings::for_remote_deployment.
  • Coordinate the public API changes through the next breaking release.

Verification

  • cargo test -p alien-manager --lib, the manager credential and full-feature infrastructure resolvers, AWS endpoint parsing, GCP/Azure setup-import ownership and dependency-drain cleanup, Azure storage-trigger reconciliation, and the full Azure worker/command-sender suites pass.
  • GCP and Azure setup already emit the concrete storage grant to the management identity, and the runtime skips its own grant creation for setup-owned imports; the CloudFormation data-layer generator test asserts the AWS management role receives the exact bucket grant while no generated managed policy carries iam:CreatePolicy/iam:AttachRolePolicy.
  • RUSTC_WRAPPER= cargo check --workspace --all-targets, the comprehensive E2E app check, provider attenuation, permission, generated-client, N-API/TypeScript, example, and smoke suites, cargo check -p alien-platform-api, Rust formatting, generator shell validation, and git diff --check pass.
  • A code-quality and security review of the current head a0d7f34d is clean at P0-P2. An earlier iteration granted the management role self-service on its own <stack>-deployment-management-* policies; because an IAM resource-name scope constrains a created policy's name and not its contents, that path could create an arbitrary-permission policy and self-attach it, so it was replaced with a setup-owned model where setup emits the concrete storage grant and the runtime never mutates IAM.
  • Fast CI passed at the current head a0d7f34d: https://github.com/alienplatform/alien/actions/runs/30090439965
  • The two packages/commands/README.md commits are documentation only and touch no code path. Their TypeScript samples were type-checked against the built package exports, and the corrected guarantees (timeoutMs is a polling budget, native caller-validation errors can surface, and token-file / HTTP(S) validation reject run asynchronously) were confirmed against the implementation.
  • Hosted three-cloud smoke validation (real AWS, GCP, and Azure put/get/head/list/delete against provisioned remote storage) is pending a real-cloud validation run.

Stacked structural PR

The structural split PR #133 is based on this branch and carries only file-decomposition changes for ALIEN-291. Merge this PR first, then retarget #133 to main and merge it.

@lilienblum lilienblum changed the title feat: add remote binding resolver feat: enable remote customer-cloud storage bindings Jul 20, 2026
@lilienblum

Copy link
Copy Markdown
Contributor Author

CI Fast reached and passed lint, TypeScript typecheck, the real bindings addon build, package-layout validation, and the full TypeScript unit suite. It then stopped on the existing alien-cloudformation::generator::aws_open_search_renders_next_gen_collection_with_data_access snapshot-order drift. The same test and field-order-only diff fail on current main in run https://github.com/alienplatform/alien/actions/runs/29750083342. This branch does not touch OpenSearch generation or that snapshot, so I have not added unrelated snapshot churn to this draft.

ALIEN-291-specific Rust, Node addon, TypeScript, IAM dataset, and generated AWS/GCP/Azure artifact checks are listed in the PR body and pass locally.

@lilienblum
lilienblum force-pushed the lilienblum/alien-291-remote-bindings branch 2 times, most recently from 658d29c to 2603348 Compare July 23, 2026 08:15
@lilienblum lilienblum closed this Jul 23, 2026
@lilienblum lilienblum reopened this Jul 23, 2026
@lilienblum
lilienblum requested a review from alongubkin July 23, 2026 14:01
@alienplatform/commands ships to npm with a blank package page. Document both
halves of the package: sending with CommandsClient (.target scoping,
CommandsClientConfig, InvokeOptions) and receiving with createCommandReceiver
(environment contract, raw byte handlers, Standard Schema validation, execution
budget, at-least-once delivery, drain semantics), plus the exported error set.

Every TypeScript sample was extracted from the README and typechecked against
the built package types with tsc --noEmit.
@lilienblum
lilienblum force-pushed the lilienblum/alien-291-remote-bindings branch from 632ac6f to 6956802 Compare July 24, 2026 04:08
lilienblum and others added 4 commits July 24, 2026 13:45
… policies (ALIEN-291)

The runtime remote-stack-management controller creates/versions/attaches
<stack>-deployment-management-* managed policies onto the <stack>-management
role after setup — how a Frozen, remote-access (BYOB) resource grants the
management identity access to a bucket whose ARN is only known post-provision.
Setup only compiled static grants for Live resources, so these calls 403'd.

Grant is scoped to this stack's own deployment-management namespace; attach is
fenced by an iam:PolicyARN condition.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant